# coding=utf-8

from PIL import Image
from pprint import pformat
from itertools import groupby
import os

replace = {
        (1,0) : "d",
        (0,1) : "r",
        (2,1) : "l",
        (1,2) : "u",
        }

groups = {
        (1,0) : "up",
        (0,1) : "left",
        (2,1) : "right",
        (1,2) : "down",
        }

mapping = {
        "u":"up",
        "d":"down",
        "l":"left",
        "r":"right"
        }
    
tiles = [
        {
            "name":"cross",
            "pattern":[
                "*x*",
                "x#x",
                "*x*"],
        },
        {
            "name":"bend",
            "pattern":[
                "*.*",
                ".#x",
                "*x*"],
        },
        {
            "name":"end",
            "pattern":[
                "*.*",
                ".#.",
                "*x*"],
        },
        {
            "name":"no",
            "pattern":[
                "*.*",
                ".#.",
                "*.*"],
            "priority": 0,
        },
        {
            "name":"straight",
            "pattern":[
                "*.*",
                "x#x",
                "*.*"],
        },
        {
            "name":"tcross",
            "pattern":[
                "*.*",
                "x#x",
                "*x*"],
        },
    ]

def makePattern(strings):
    pattern = {}
    for y, row in enumerate(strings):
        for x, c in enumerate(row):
            pattern[x,y] = c
    return pattern

def fillPattern(pattern, customChar=None):
    res = {}
    for y in range(3):
        for x in range(3):
            p = pattern[x,y]
            res[x,y] = (p if p != 'x' else (replace[x,y] if customChar is None else customChar))
    return res

def generateGroups(pattern):
    """Pattern: [x,y]"""
    grps = []
    for x in range(3):
        for y in range(3):
            if pattern[x,y] not in "udlr": continue
            try:
                grps.append(groups[x,y])
            except KeyError:
                pass
    return grps

def fillInfo(info):
    tileInfo = {
            "gruops":[],
            "anchor": (1,1),
            "priority":5,
            "mapping":dict(mapping),
            }
    for key in ("anchor", "groups", "priority", "mapping", "pattern", "imageName"):
        try:
            tileInfo[key] = info[key]
        except KeyError:
            pass
    return tileInfo

def rotatePattern(pattern):
    res = {}
    h = 1+max(y for x,y in pattern.keys())
    for (x,y),c  in pattern.items():
        res[h-1-y,x] = c
    return res

def patternToString(pattern):
    res = []
    key = lambda x: x[0][1]
    for y, items in groupby(sorted(pattern.items(), key=(lambda x: (x[0][1], x[0][0]))), key):
        res.append("".join(c for xy, c in items))
    return "\n".join(res)

def generateTiles(info, currentDir):
    result = []
    img = Image.open(os.path.join(currentDir, info["name"]+".png"))
    w,h = img.size
    image = Image.new("RGBA", (3*w,3*h), (255,255,255,0))
    image.paste(img, (w,h))

    pattern = makePattern(info["pattern"])
    for i in range(4):
        p = fillPattern(pattern)
        info["pattern"] = patternToString(p)
        info["groups"] = generateGroups(p)

        imageName = os.path.join("images", "{0}-{1}.png".format(info["name"], i))
        image.save(os.path.join(currentDir, imageName))
        info["imageName"] = imageName
        tile = fillInfo(info)
        result.append(tile)
        tile = dict(tile)
        tile["priority"] = 1
        tile["pattern"] = patternToString(fillPattern(pattern, "#"))
        result.append(tile)

        image = image.rotate(-90)
        pattern = rotatePattern(pattern)
    return result


def generateAll():
    currentDir = os.path.dirname(os.path.realpath(__file__))
    imagesDir = os.path.join(currentDir, "images")
    try:
        os.mkdir(imagesDir)
    except OSError:
        pass
    tileInfo = []
    for info in tiles:
        tileInfo.extend(generateTiles(info, currentDir))
    with open(os.path.join(currentDir, "tiles.py"), "w") as f:
        f.write("# coding=utf-8\nsorter = \"black_white_dfs\"\ntiles = {0}\n".format(pformat(tileInfo)).encode("utf-8"))
    

